#ifndef _MEDIATYPE_HPP_
#define _MEDIATYPE_HPP_

#include "jhdefs.hpp"
#include "net/NameValueCollection.hpp"
#include <string>
NET_NAMESPACE_BEGIN

//RFC 2045 and RFC 2046
class CMediaType
{
public:
	CMediaType(const std::string& mediaType);
	CMediaType(const std::string& type, const std::string& subType);
	CMediaType(const CMediaType& mediaType);
	~CMediaType();
	CMediaType& operator = (const CMediaType& mediaType);
	CMediaType& operator = (const std::string& mediaType);

	void swap(CMediaType& mediaType);

	void setType(const std::string& type);
	const std::string& getType() const;

	void setSubType(const std::string& subType);
	const std::string& getSubType() const;

	void setParameter(const std::string& name, const std::string& value);
	const std::string& getParameter(const std::string& name) const;
	bool hasParameter(const std::string& name) const;
	void removeParameter(const std::string& name);

	const CNameValueCollection& parameters() const;

	std::string toString() const;

	bool matches(const CMediaType& mediaType) const;
	bool matches(const std::string& type, const std::string& subType) const;
	bool matches(const std::string& type) const;

	bool matchesRange(const CMediaType& mediaType) const;
	bool matchesRange(const std::string& type, const std::string& subType) const;
	bool matchesRange(const std::string& type) const;

protected:
	void parse(const std::string& mediaType);

private:
	CMediaType();

	std::string				m_type;
	std::string				m_subType;
	CNameValueCollection	m_parameters;
};

inline void swap(CMediaType& m1, CMediaType& m2)
{
	m1.swap(m2);
}

NET_NAMESPACE_END

#endif
